//
//  SFAnimatedImageView.swift
//  SeeFM_Swift
//
//  Created by CBCT_MBP on 2021/5/25.
//

import UIKit

import YYKit.NSAttributedString_YYText

let kANIMATEDVIEWTAG: NSInteger = 1100001


/// GIF 动画或 webp 动画
class SFAnimatedImageView: YYAnimatedImageView {
    
    private var loopCount: NSInteger?
    private var curLoop: NSInteger?
    private var finishClosure: (()->())?
    
    
    /// 动画
    /// - Parameters:
    ///   - inView: 承载视图
    ///   - frame: 尺寸
    ///   - image: 图片
    ///   - contentMode: 填充模式
    ///   - hideOrigin: 是否播放时隐藏原视图
    ///   - loopCount: 动画循环次数
    ///   - allowOverlay: 是否允许多次添加
    ///   - finish: 完成回调
    /// - Returns: 动画View
    class func animatedAt(inView: UIView,
                          frame: CGRect,
                          image: YYImage?,
                          contentMode: ContentMode,
                          hideOrigin: Bool = false,
                          loopCount: NSInteger = 1,
                          allowOverlay: Bool = false,
                          finish: (()->())?) -> SFAnimatedImageView? {
        
        guard let _ = inView.superview?.viewWithTag(kANIMATEDVIEWTAG), allowOverlay == false else {
            finish?()
            return nil
        }
        guard let superView = inView.superview else {
            finish?()
            return nil
        }
        guard let img = image else {
            finish?()
            return nil
        }
        
        inView.isHidden = hideOrigin
        
        let animatedView = SFAnimatedImageView.init(frame: frame)
        animatedView.contentMode = contentMode
        animatedView.finishClosure = {
            inView.isHidden = false
            finish?()
        }
        animatedView.loopCount = loopCount
        animatedView.tag = kANIMATEDVIEWTAG
        if img.animatedImageType == .GIF || img.animatedImageType == .webP {
            animatedView.image = img
            animatedView.curLoop = 1
            superView.insertSubview(animatedView, aboveSubview: inView)
        }
        
        return animatedView
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)

        addObserver(self, forKeyPath: "currentAnimatedImageIndex", options: .new, context: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        let currentAnimatedImageIndex: Int = change?[NSKeyValueChangeKey.newKey] as! Int
        if currentAnimatedImageIndex == 0 , currentIsPlayingAnimation {
            if loopCount == curLoop {
                isHidden = true
                stopAnimating()
                removeObserver(self, forKeyPath: "currentAnimatedImageIndex")
                removeFromSuperview()
                finishClosure?()
            }else {
                curLoop? += 1
            }
        }
    }

}



/// 序列帧动画
class SFAnimatedFrameImageView: UIImageView, CAAnimationDelegate {
    
    var keyframeName: String?
    var finishClosure: (()->())?
    
    class func animatedAt(inView: UIView,
                          frame: CGRect,
                          frameCount: UInt,
                          imageName: String?,
                          hideOrigin: Bool = false,
                          finish: (()->())?) -> SFAnimatedFrameImageView? {
      
        if inView.superview?.viewWithTag(kANIMATEDVIEWTAG) != nil {
            return nil
        }
        guard let _ = inView.superview else {
            finish?()
            return nil
        }
        guard let imgName = imageName, frameCount != 0 else {
            finish?()
            return nil
        }
        
        inView.isHidden = hideOrigin
        let animatedView = SFAnimatedFrameImageView.init(frame: frame)
        animatedView.contentMode = .scaleAspectFit
        animatedView.finishClosure = {
            inView.isHidden = false
            finish?()
        }
        
        animatedView.tag = kANIMATEDVIEWTAG
        animatedView.startAnimate(frameName: imgName, count: frameCount)
        inView.superview?.insertSubview(animatedView, aboveSubview: inView)
        
        return animatedView
    }
    
    func startAnimate(frameName: String, count: UInt) {
        
        var array = [Any]()
        for index in 1...count {
            
            let fileName = NSString.init(format: "%@%02d.png", frameName,index)
            
            guard let path = Bundle.main.path(forResource: fileName as String, ofType: nil) else { return }
            
            let image = UIImage.init(contentsOfFile: path)
            if index == 1 {
                self.image = image
            }
            
            guard let cgImg = image?.cgImage else {return}
            array.append(cgImg)
        }
        
        let mKeyframeAnimation = CAKeyframeAnimation.init(keyPath: "contents")
        mKeyframeAnimation.delegate = self
        mKeyframeAnimation.duration = Double(array.count) * 0.04
        mKeyframeAnimation.repeatCount = 1
        mKeyframeAnimation.values = array
        mKeyframeAnimation.isRemovedOnCompletion = false
        mKeyframeAnimation.fillMode = .forwards
        layer.add(mKeyframeAnimation, forKey: "FrameAnimationKey")
        
    }
    
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        finishClosure?()
        layer.removeAnimation(forKey: "FrameAnimationKey")
        removeFromSuperview()
    }
}
